package com.hose.proxy;

import com.hose.annotion.CustomProxy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 本类的作用是为使用了CustomProxy注解的类创建代理对象，当代理对象的方法被调用时，会发送一个HTTP请求，并返回请求的结果
 */
public class CustomProxyHandler implements InvocationHandler {
    //RestTemplate是Spring提供的用于发送HTTP请求的工具
    RestTemplate restTemplate = new RestTemplate();

    //代理对象的方法被调用时，准确的说是当调用MyService接口中的test方法时就会执行invoke()方法
    //proxy：代表代理对象，method：代表被代理的方法对象，args：代表被代理方法的参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //首先获取被代理方法所在类的class对象
        Class<?> declaringClass = method.getDeclaringClass();
        //判断当前的被代理对象是否使用了自定义的CustomProxy注解，没有使用则直接返回 null
        if (declaringClass.isAnnotationPresent(CustomProxy.class)) {
            //如果使用了自定义注解，那么就获取自定义注解
            CustomProxy annotation = declaringClass.getAnnotation(CustomProxy.class);
            //获取注解中的属性值
            String service = annotation.service();
            String address = annotation.address();
            String url = address + service;
            //获取方法上的注解,获取请求路径,拼接url
            RequestMapping annotation1 = method.getAnnotation(RequestMapping.class);
            url = url + annotation1.value()[0];
            //判断方法是否有参数，如果方法有参数，就将参数传递给 getForObject 方法；如果没有参数，就只传递 URL 和返回类型。
            if (args != null && args.length != 0) {
                System.out.println("代理对象的方法被调用了");
                return restTemplate.getForObject(url, method.getReturnType(), args);
            } else {
                System.out.println("代理对象的方法被调用了");
                return restTemplate.getForObject(url, method.getReturnType());
            }
        } else {
            return null;
        }
    }
}
